home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / IFC_112 / netscape / application / Range.java < prev    next >
Encoding:
Text File  |  1999-05-28  |  8.4 KB  |  324 lines  |  [TEXT/CWIE]

  1. // Range.java
  2. // By Ned Etcode
  3. // Copyright 1996, 1997 Netscape Communications Corp.  All rights reserved.
  4.  
  5. package netscape.application;
  6.  
  7. import java.lang.*;
  8. import netscape.util.*;
  9.  
  10.  
  11. /** Object subclass representing a range of indexed data. A Range consists of
  12.   * an index location and a length.
  13.   * @note 1.0 fixed bug in contains()
  14.   */
  15.  
  16. public class Range extends Object implements Codable {
  17.  
  18.     /** A null (undefined) range. */
  19.     private static Range nullRange;
  20.  
  21.     /** The Range's first index. */
  22.     public int index;
  23.  
  24.     /** The Range's length. */
  25.     public int length;
  26.  
  27.     static final String         INDEX_KEY = "index";
  28.     static final String         LENGTH_KEY = "length";
  29.  
  30.  
  31.  
  32.     /* static methods */
  33.  
  34.     public static Range nullRange() {
  35.         if (nullRange == null) {
  36.             nullRange = new Range(-1,0);
  37.         }
  38.  
  39.         return nullRange;
  40.     }
  41.  
  42.     /** Returns the intersection of <b>range1</b> and <b>range2</b>.
  43.       */
  44.     public static Range rangeFromIntersection(Range range1, Range range2) {
  45.         Range   newRange;
  46.  
  47.         newRange = new Range(range1);
  48.         newRange.intersectWith(range2);
  49.  
  50.         return newRange;
  51.     }
  52.  
  53.     /** Returns the union of <b>range1</b> and <b>range2</b>.
  54.       */
  55.     public static Range rangeFromUnion(Range range1, Range range2) {
  56.         Range   newRange;
  57.  
  58.         newRange = new Range(range1);
  59.         newRange.unionWith(range2);
  60.  
  61.         return newRange;
  62.     }
  63.  
  64.     /** Returns a Range containing <b>index1</b> and <b>index2</b>.
  65.       */
  66.     public static Range rangeFromIndices(int index1, int index2) {
  67.         if( index1 < index2 )
  68.             return new Range(index1,index2-index1);
  69.         else
  70.             return new Range(index2,index1-index2);
  71.  
  72.     }
  73.  
  74.  
  75.  
  76.     /* constructors */
  77.  
  78.     /** Constructs a Range with value Range.nullRange().   */
  79.     public Range() {
  80.         super();
  81.         index = nullRange().index;
  82.         length= nullRange().length;
  83.     }
  84.  
  85.     /** Constructs a Range with index <b>index</b> and length <b>length</b>.
  86.       */
  87.     public Range(int index, int length) {
  88.         super();
  89.         this.index  = index;
  90.         this.length = length;
  91.     }
  92.  
  93.     /** Constructs a Range with the same index and length as
  94.       * <b>templateRange</b>.
  95.       */
  96.     public Range(Range templateRange) {
  97.         super();
  98.         index = templateRange.index;
  99.         length = templateRange.length;
  100.     }
  101.  
  102.     /** Returns the Range's first index.
  103.       */
  104.     public int index() {
  105.         return index;
  106.     }
  107.  
  108.     /** Returns the Range's length.
  109.       */
  110.     public int length() {
  111.         return length;
  112.     }
  113.  
  114.     /** Returns the last index included in the Range.
  115.       * <i>Note: If range length is zero, the return value
  116.       * is undefined.</i>
  117.       */
  118.     public int lastIndex() {
  119.         return index + length - 1;
  120.     }
  121.  
  122.     /** Returns <b>true</b> if the Range equals <b>anObject</b>.
  123.       */
  124.     public boolean equals(Object anObject) {
  125.         Range aRange;
  126.  
  127.         if(!(anObject instanceof Range))
  128.             return false;
  129.  
  130.         aRange = (Range) anObject;
  131.         if( aRange.index == index && aRange.length == length )
  132.             return true;
  133.         else
  134.             return false;
  135.     }
  136.  
  137.     /** Computes the union of the Range and <b>aRange</b>. Stores the result in
  138.       * the receiver.  If the Range and <b>aRange</b> do not intersect, the
  139.       * union consists of the range from the minimum index to the maximum
  140.       * index.
  141.       */
  142.     public void unionWith(Range aRange) {
  143.         unionWith(aRange.index, aRange.length);
  144.     }
  145.  
  146.     /** Computes the union of the Range and the range defined by
  147.       * <b>anIndex</b> and <b>aLength</b>. Stores the result in the receiver.
  148.       * If the ranges do not intersect, the union consists of the range from
  149.       * the minimum index to the maximum index.
  150.       */
  151.     public void unionWith(int anIndex, int aLength) {
  152.         int low,high;
  153.  
  154.         if( index == nullRange().index ) {
  155.             index = anIndex;
  156.             length = aLength;
  157.         } else if( anIndex == nullRange().index ) {
  158.             return;
  159.         } else {
  160.             if( index < anIndex )
  161.                 low = index;
  162.             else
  163.                 low = anIndex;
  164.             if( (index+length) > (anIndex + aLength))
  165.                 high = index + length;
  166.             else
  167.                 high = anIndex + aLength;
  168.             index = low;
  169.             length = high - low;
  170.         }
  171.     }
  172.  
  173.     /** Computes the intersection of the Range and <b>aRange</b>. Stores
  174.       * the result in the receiver. The result is Range.nullRange() if the
  175.       * ranges do not intersect.
  176.       */
  177.     public void intersectWith(Range aRange) {
  178.         intersectWith(aRange.index, aRange.length);
  179.     }
  180.  
  181.     /** Computes the intersection of the Range and the range defined by
  182.       * <b>anIndex</b> and <b>aLength</b>. Stores the result in the receiver.
  183.       * The result is Range.nullRange() if the ranges do not intersect.
  184.       */
  185.     public void intersectWith(int anIndex, int aLength) {
  186.         int lowIndex,lowLength;
  187.         int highIndex,highLength;
  188.  
  189.         if( index < anIndex ) {
  190.             lowIndex  = index;
  191.             lowLength = length;
  192.             highIndex  = anIndex;
  193.             highLength = aLength;
  194.         } else {
  195.             lowIndex = anIndex;
  196.             lowLength = aLength;
  197.             highIndex = index;
  198.             highLength = length;
  199.         }
  200.  
  201.         if( (lowIndex+lowLength) <= highIndex ) {
  202.             index  = nullRange().index;
  203.             length = nullRange().length;
  204.         } else {
  205.             index  = highIndex;
  206.             if( (highIndex + highLength) > (lowIndex + lowLength) )
  207.                 length = (lowIndex + lowLength) - highIndex;
  208.             else
  209.                 length = highLength;
  210.         }
  211.     }
  212.  
  213.     /** Returns the Range's String representation.
  214.       */
  215.     public String toString() {
  216.         if( isNullRange() )
  217.             return "Null range";
  218.         else
  219.             return "(" + index + ", " + length + ")";
  220.     }
  221.  
  222.  
  223.   /*
  224.    * Conveniences
  225.    */
  226.  
  227.     /** Returns <b>true</b> if the receiver intersects <b>aRange</b>.
  228.       */
  229.     public boolean intersects(Range aRange) {
  230.         boolean result;
  231.         int oldIndex = index;
  232.         int oldLength = length;
  233.  
  234.         this.intersectWith( aRange );
  235.         if( index == nullRange().index )
  236.             result = false;
  237.         else
  238.             result = true;
  239.         index = oldIndex;
  240.         length = oldLength;
  241.         return result;
  242.     }
  243.  
  244.     /** Returns <b>true</b> if the receiver intersects the range defined by
  245.       * <b>anIndex</b> and <b>aLength</b>.
  246.       */
  247.     public boolean intersects(int anIndex, int aLength) {
  248.         boolean result;
  249.         int oldIndex = index;
  250.         int oldLength = length;
  251.  
  252.         this.intersectWith( anIndex, aLength );
  253.         if( index == nullRange().index )
  254.             result = false;
  255.         else
  256.             result = true;
  257.         index = oldIndex;
  258.         length = oldLength;
  259.         return result;
  260.     }
  261.  
  262.     /** Returns <b>true</b> if the receiver equals Range.nullRange().
  263.       */
  264.     public boolean isNullRange() {
  265.         if( index == nullRange().index )
  266.             return true;
  267.         else
  268.             return false;
  269.     }
  270.  
  271.     /** Returns <b>true</b> the range has a length of zero.
  272.       */
  273.     public boolean isEmpty() {
  274.         if( length == 0 )
  275.             return true;
  276.         else
  277.             return false;
  278.     }
  279.  
  280.     /** Returns <b>true</b> if the Range includes <b>anIndex</b>.
  281.       */
  282.     public boolean contains(int anIndex) {
  283.         if( anIndex >= index && anIndex < (index+length))
  284.             return true;
  285.         else
  286.             return false;
  287.     }
  288.  
  289.  
  290. /* archiving */
  291.  
  292.  
  293.     /** Describes the Range class' coding information.
  294.       * @see Codable#describeClassInfo
  295.       */
  296.     public void describeClassInfo(ClassInfo info) {
  297.         info.addClass("netscape.application.Range", 1);
  298.         info.addField(INDEX_KEY, INT_TYPE);
  299.         info.addField(LENGTH_KEY, INT_TYPE);
  300.     }
  301.  
  302.     /** Encodes the Range.
  303.       * @see Codable#encode
  304.       */
  305.     public void encode(Encoder encoder) throws CodingException {
  306.         encoder.encodeInt(INDEX_KEY, index);
  307.         encoder.encodeInt(LENGTH_KEY, length);
  308.     }
  309.  
  310.     /** Decodes the Range.
  311.       * @see Codable#decode
  312.       */
  313.     public void decode(Decoder decoder) throws CodingException {
  314.         index = decoder.decodeInt(INDEX_KEY);
  315.         length = decoder.decodeInt(LENGTH_KEY);
  316.     }
  317.  
  318.     /** Finishes the Range decoding.
  319.       * @see Codable#finishDecoding
  320.       */
  321.     public void finishDecoding() throws CodingException {
  322.     }
  323. }
  324.